﻿/* 
 * Copyright 2010 Justin Pealing
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */

using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using Minnow.Web.FastCGI;
using Minnow.Web.Native;

namespace Minnow.Web.FastCGITest
{
    /// <summary>
    /// FastCGI server implementation
    /// </summary>
    public class FastCGI
    {
        public static FastCGIStream StartFastCGIProcess(string CommandLine)
        {
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listener.Bind(new IPEndPoint(IPAddress.Any, 8221));
            listener.Listen(1);

            SafeFileHandle childHandle;
            if (!NativeMethods.DuplicateHandle(
                NativeMethods.GetCurrentProcess(),
                new SafeFileHandle(listener.Handle, false),
                NativeMethods.GetCurrentProcess(),
                out childHandle,
                0,
                true,
                NativeMethods.DUPLICATE_SAME_ACCESS))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            CreateProcess process = new CreateProcess();
            process.StartInfo.CommandLine = CommandLine;
            process.StartInfo.WorkingDirectory = Path.GetDirectoryName(CommandLine);
            process.StartInfo.StandardInput = childHandle;
            process.StartInfo.StandardOutput = new SafeFileHandle(NativeMethods.INVALID_HANDLE_VALUE, false);
            process.StartInfo.StandardError = new SafeFileHandle(NativeMethods.INVALID_HANDLE_VALUE, false);
            process.StartInfo.UseStandardHandles = true;

            process.Start();

            return new FastCGIStream(listener);
        }
    }
}
